/**
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *    
 *    Linking this library statically or dynamically with other modules 
 *    is making a combined work based on this library. Thus, the terms and
 *    conditions of the GNU General Public License cover the whole
 *    combination.
 *    
 *    As a special exception, the copyright holders of this library give 
 *    you permission to link this library with independent modules to 
 *    produce an executable, regardless of the license terms of these 
 *    independent modules, and to copy and distribute the resulting 
 *    executable under terms of your choice, provided that you also meet, 
 *    for each linked independent module, the terms and conditions of the 
 *    license of that module.  An independent module is a module which 
 *    is not derived from or based on this library.  If you modify this 
 *    library, you may extend this exception to your version of the 
 *    library, but you are not obligated to do so.  If you do not wish 
 *    to do so, delete this exception statement from your version.
 *
 *    Project: Financas Pessoais
 *    Author : Igor Salles
 */
package org.fp.miscs;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * interface modelo para guardar anotacoes pessoais para modelos de design 
 * Singleton eh um modelo que permite uma unico objeto de um dado tipo em qual
 * quer momento da execucao de um dado sistema.
 * Uma boa dica que encontrei para a implementacao do modelo em java foi:
 * O primeiro passo para o seu singleton é remover todos os atributos estáticos. 
 * Se você terá somente uma instância dessa classe, pode usar os atributos dessa 
 * instância.
 * Projete a classe normalmente, como se ela não fosse um singleton, depois:
 *      1. Deixe o seu construtor privado;
 *      2. Crie o atributo estático para a instância única da sua classe;
 *      3. Crie o método estático para obter essa instância.  *
 * 
 * neste modelo peguei uma copia de uma conexao com um banco de dados.
 * 
 * @author iroiro
 */
public class SingletonModel {

    //campo/atributo/objeto estatico para instancia unica da classe
    private static SingletonModel instancia = null;
    //campos/atributos/objetos privados
    private static Connection conn = null; //static para so existir 1 no classloader
    private String user; //usuario do banco de dados
    private String password; //senha para o banco
    private String dbClass; //classe/conector jdbc  
    private String db; //nome do banco de dados
    private String dbUrl; //url jdbc
    private String port; //porta para acesso
    private static String ip; //ip para o servidor
    
    //private para ser limitar a instanciacao
    //no entanto pode ser instanciada dentro do mesmo pacote
    //protected nao permite que o construtor seja chamado de outra classe.
    protected SingletonModel() throws ClassNotFoundException, SQLException {
        instancia.configure();
        if (conn == null){
        Class.forName(dbClass);
        conn = DriverManager.getConnection(
                dbUrl + ":" + db + ":" + port,
                user,
                password);
        }        
    }

    public synchronized static SingletonModel getInstance()
            throws ClassNotFoundException, SQLException {
        if (instancia == null) {
            instancia = new SingletonModel();
        }
        return instancia;
    }

    public Connection getConnection()
            throws ClassNotFoundException, SQLException {
        if (conn == null) {
            this.getInstance();
        }
        return conn;
    }


    private void configure() {
    }
}





/**
// * A simple wrapper around JDK logging facilities.
// * 
// * @author Igor Salles
// * @since may 14, 2011
// * @created may 14, 2011
// */
//public class Jornal {
//    /* 
//     * esta eh uma classe que pretendo utilizar como singleton. a principio
//     * o debug do projeto sera enviado para arquivo e console, e mais tarde
//     * somente para arquivo, ja que uma das interfaces de usuaria sera a de
//     * texto. 
//     * Para classes singleton temos que:
//     *  - Deixe o seu construtor privado;
//     *  - Crie o atributo estático para a instância única da sua classe;
//     *  - Crie o método estático para obter essa instância. 
//     */
//    //instancia unica da classe
//    private static Jornal instance;
//    //variaves e campos da classe
//    //propriedades de configuracao do logger
//    private Logger jornalLogger;
//    
//    //Construtor unico da classe
//    private Jornal(){
//        //
//        }
//    //metodo estatico para obeter a instancia
//    public static synchronized Jornal getInstance(){
//        return new Jornal();
//    }
//    
//    public void configure(){
//        //
//        Properties props = new Properties();
//    }
//    
//}


//modo 1
//
//    ...  
//    private static final Resource resource = new Resource();  
//    ...  
//    public static Resource getResource() {  
//       return resource;  
//    }  
//
//
//
//
//modo 2
//
//    ...  
//    private static final Resource resource = null;  
//    ...  
//    public static synchronized Resource getResource() {  
//       if (resource == null) {  
//           resource = new Resource();  
//       }  
//       return resource;  
//    }  
//
//
//
//modo 3 (este é classificado como um anti-pattern)
//
//    ...  
//    private static final Resource resource = null;  
//    ...  
//    public static synchronized Resource getResource() {  
//       if (resource == null) {  
//           synchronized (Resource.class) {  
//              if (resource == null) {  
//                 resource = new Resource();  
//              }  
//           }  
//       return resource;  
//       }  
//    }  
//
//
//
//modo 4
//
//    private static class ResourceHolder {  
//        public static final Resource = new Resource();  
//    }  
//      
//    ...  
//    public static Resource getResource() {  
//         return ResourceHolder.resource;  
//    }  
//    ...  

